#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include "ayoo.h"

#define LOG_DEB(msg) \
std::cout<<"["<<__FILE__<<":"<<__FUNCTION__<<":"<<__LINE__<<"] "<<msg<<std::endl


/**
 * @brief data-storage for testzjd
 * @remarks generated-code.
 */
class Testzjd:public AYOO::BaseRow
{
public:
	uint32_t id;
	std::string name;
	char gender;
	std::string address;
private:
	bool __id_changed;
	bool __name_changed;
	bool __gender_changed;
	bool __address_changed;
public:
	Testzjd()
	: AYOO::BaseRow()
	{
		this->id = 0;
		this->name = "";
		this->gender = 0;
		this->address = "";
	}

	~Testzjd()
	{}
	
	void Escape()
	{
		AYOO::MySQLWrap::EscapeString( this->name );
		AYOO::MySQLWrap::EscapeString( this->address );
	}

};


/**
 * @brief data-DBI for testzjd
 * @remarks generated-code.
 */
class DBITestzjd:public AYOO::BaseDBI
{
public:
	DBITestzjd(const std::string sHost, uint32_t iPort, const std::string &sUser, const std::string &sPswd)
	: AYOO::BaseDBI( sHost, iPort, sUser, sPswd)
	{
		LOG_DEB("concrete-init.");
	}

	DBITestzjd(const AYOO::Config& conf)
	: AYOO::BaseDBI(conf, "DB_HOST", "DB_PORT", "DB_USER", "DB_PSWD" )
	{
	}

	uint32_t Insert(Testzjd &in_Testzjd);
	uint32_t SelectOne(uint32_t id, Testzjd &out_Testzjd);
	uint32_t Select(const std::string sCondition, uint32_t iStart, uint32_t iLimit, std::vector<Testzjd> &outlist_Testzjd);
	uint32_t Count(const std::string sCondition);
	uint32_t UpdateOne(Testzjd &in_Testzjd);
	uint32_t Update(const std::string sCondition, Testzjd &in_Testzjd);
	uint32_t DeleteOne(uint32_t id);
	uint32_t Delete(const std::string sCondition);
};

#define SQL_TESTZJD_INSERT "INSERT INTO test.testzjd SET name='%s', gender=%d, address='%s';"
#define SQL_TESTZJD_SELECTONE "SELECT * FROM test.testzjd WHERE id=%d;"
#define SQL_TESTZJD_SELECT "SELECT * FROM test.testzjd WHERE %s LIMIT %d,%d;"
#define SQL_TESTZJD_COUNT "SELECT COUNT(*) AS _COUNT FROM test.testzjd WHERE %s;"
#define SQL_TESTZJD_UPDATEONE "UPDATE test.testzjd SET name='%s', gender=%d, address='%s' WHERE id=%d;"
#define SQL_TESTZJD_UPDATE "UPDATE test.testzjd SET name='%s', gender=%d, address='%s' WHERE %s;"
#define SQL_TESTZJD_DELETEONE "DELETE FROM test.testzjd WHERE id=%d;"
#define SQL_TESTZJD_DELETE "DELETE FROM test.testzjd WHERE %s;"

//INSERT INTO test.testzjd SET name='%s', gender=%d, address='%s';
uint32_t DBITestzjd::Insert(Testzjd &in_Testzjd)
{
	LOG_DEB(".");
	AYOO::MySQLWrap mys= *( this->GetMySQL() );
	try
	{
		mys.Connect(this->m_sHost, this->m_iPort, this->m_sUser, this->m_sPswd);
		in_Testzjd.Escape();
		mys.QueryWith(SQL_TESTZJD_INSERT
			, in_Testzjd.name.c_str()
			, in_Testzjd.gender
			, in_Testzjd.address.c_str()
		);
	}
	catch(AYOO::AyooException &ex)
	{
		LOG_DEB(ex.what());
	}
	mys.Close();
	
	return 0;
}

uint32_t DBITestzjd::SelectOne(uint32_t id, Testzjd &out_Testzjd)
{
	LOG_DEB(".");
	AYOO::MySQLWrap mys= *( this->GetMySQL() );
	int32_t iRes = 0;
	try
	{
		mys.Connect(this->m_sHost, this->m_iPort, this->m_sUser, this->m_sPswd);
		mys.QueryWith(SQL_TESTZJD_SELECTONE
			, id
		);
		mys.StoreResult();
		if(mys.FetchRow())
		{
			out_Testzjd.id = mys.GetField_Int("id");
			out_Testzjd.name = mys.GetField_String("name");
			out_Testzjd.gender = mys.GetField_Int("gender");
			out_Testzjd.address = mys.GetField_String("address");
			iRes = 1;
		}
		mys.Close();
	}
	catch(AYOO::AyooException &ex)
	{
		LOG_DEB(ex.what());
	}
	mys.Close();
	return iRes;
}

uint32_t DBITestzjd::Select(const std::string sCondition, uint32_t iStart, uint32_t iLimit, std::vector<Testzjd> &outlist_Testzjd)
{
	AYOO::MySQLWrap mys= *( this->GetMySQL() );
	try
	{
		mys.Connect(this->m_sHost, this->m_iPort, this->m_sUser, this->m_sPswd);
		mys.QueryWith(SQL_TESTZJD_SELECT
			, sCondition.c_str()
			, iStart
			, iLimit
		);
		mys.StoreResult();
		while(mys.FetchRow())
		{
			Testzjd st;
			st.id = mys.GetField_Int("id");
			st.name = mys.GetField_String("name");
			st.gender = mys.GetField_Int("gender");
			st.address = mys.GetField_String("address");
			outlist_Testzjd.push_back(st);
		}
		mys.Close();
	}
	catch(AYOO::AyooException &ex)
	{
		LOG_DEB(ex.what());
	}
	mys.Close();
	return outlist_Testzjd.size();
}

uint32_t DBITestzjd::Count(const std::string sCondition)
{
	LOG_DEB(".");
	AYOO::MySQLWrap mys= *( this->GetMySQL() );
	int32_t iCount = 0;
	try
	{
		mys.Connect(this->m_sHost, this->m_iPort, this->m_sUser, this->m_sPswd);
		mys.QueryWith(SQL_TESTZJD_SELECTONE
			, sCondition.c_str()
		);
		mys.StoreResult();
		if(mys.FetchRow())
		{
			iCount = mys.GetField_Int("_COUNT");
		}
		mys.Close();
	}
	catch(AYOO::AyooException &ex)
	{
		LOG_DEB(ex.what());
	}
	mys.Close();
	return iCount;
}

uint32_t DBITestzjd::UpdateOne(Testzjd &in_Testzjd)
{
	LOG_DEB(".");
	AYOO::MySQLWrap mys= *( this->GetMySQL() );
	try
	{
		mys.Connect(this->m_sHost, this->m_iPort, this->m_sUser, this->m_sPswd);
		in_Testzjd.Escape();
		mys.QueryWith(SQL_TESTZJD_UPDATEONE 
			, in_Testzjd.name.c_str()
			, in_Testzjd.gender
			, in_Testzjd.address.c_str()
			, in_Testzjd.id
		);
	}
	catch(AYOO::AyooException &ex)
	{
		LOG_DEB(ex.what());
	}
	mys.Close();
	
	return 0;
}

uint32_t DBITestzjd::Update(const std::string sCondition, Testzjd &in_Testzjd)
{
	LOG_DEB(".");
	AYOO::MySQLWrap mys= *( this->GetMySQL() );
	try
	{
		mys.Connect(this->m_sHost, this->m_iPort, this->m_sUser, this->m_sPswd);
		in_Testzjd.Escape();
		mys.QueryWith(SQL_TESTZJD_UPDATE
			, in_Testzjd.name.c_str()
			, in_Testzjd.gender
			, in_Testzjd.address.c_str()
			, sCondition.c_str()
		);
	}
	catch(AYOO::AyooException &ex)
	{
		LOG_DEB(ex.what());
	}
	mys.Close();
	return 0;
}

uint32_t DBITestzjd::DeleteOne(uint32_t id)
{
	LOG_DEB(".");
	AYOO::MySQLWrap mys= *( this->GetMySQL() );
	try
	{
		mys.Connect(this->m_sHost, this->m_iPort, this->m_sUser, this->m_sPswd);
		mys.QueryWith(SQL_TESTZJD_DELETEONE
			, id
		);
	}
	catch(AYOO::AyooException &ex)
	{
		LOG_DEB(ex.what());
	}
	mys.Close();
	return 0;
}

uint32_t DBITestzjd::Delete(const std::string sCondition)
{
	LOG_DEB(".");
	AYOO::MySQLWrap mys= *( this->GetMySQL() );
	try
	{
		mys.Connect(this->m_sHost, this->m_iPort, this->m_sUser, this->m_sPswd);
		mys.QueryWith(SQL_TESTZJD_DELETE
			, sCondition.c_str()
		);
	}
	catch(AYOO::AyooException &ex)
	{
		LOG_DEB(ex.what());
	}
	mys.Close();
	return 0;
}


void test_insert(DBITestzjd &dbiTestzjd)
{
	Testzjd testzjd;
	char buff[128];
	for(uint32_t i=0; i<20; i++)
	{
		memset( buff, 0x00, sizeof(buff) );
		sprintf( buff, "moomin%03d", i );
		//testzjd.id = i;
		testzjd.name = buff;
		testzjd.gender = i%2;
		testzjd.address = "nanshan district. sz.";
		printf(".name:%s,%s, addr:%s\n", buff, testzjd.name.c_str(), testzjd.address.c_str() );
		dbiTestzjd.Insert(testzjd);
	}

}

void test_select(DBITestzjd &dbiTestzjd)
{
	std::vector<Testzjd> v_out;
	dbiTestzjd.Select("1=1", 0, 10, v_out);
	for(uint32_t i=0; i<v_out.size(); i++)
	{
		Testzjd &st = v_out[i];
		printf("id:%d, name:%s, gender:%d, address:%s\n"
			,st.id, st.name.c_str(), st.gender, st.address.c_str()
		);
	}
}

int32_t main(int32_t argc, char* argv[])
{
	AYOO::GlobalConfig &conf = AYOO::GlobalConfig::GetInstance();
	conf.Read("./test_demo.conf");

	DBITestzjd dbiTestzjd(conf);
	//test_insert(dbiTestzjd);
	test_select(dbiTestzjd);
	
        return 0;
}

